package org.summer.common.http;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;

import static org.summer.common.constant.DateTime.DATE_TIME_FORMAT_MS;

/**
 * 全局同意http响应反回信息载体类
 * @author wjj9132
 * @date 2024/9/26 8:41
 * @since 1.0
 * @param <T> 泛型参数，用于封装不同类型的数据
 */
@Data
public class Result<T> implements Serializable {
    /**
     * 响应状态码
     */
    private int code;
    /**
     * 响应消息
     */
    private String message;
    /**
     * 响应数据转态,如果为true则表示有数据
     */
    private boolean success;
    /**
     * 响应时间戳
     */
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = DATE_TIME_FORMAT_MS)
    private LocalDateTime timestamp;
    /**
     * 响应数据
     */
    private T data;

    private Result() {
        this.timestamp = LocalDateTime.now();
    }

    private Result(int code, String message, boolean success, T data) {
        this.code = code;
        this.message = message;
        this.success = success;
        this.data = data;
        this.timestamp = LocalDateTime.now();
    }

    /**
     * 构建一个空的响应
     * @param <T> 响应数据类型
     */
    public static <T> Result<T> empty() {
        return new Result<T>();
    }

    /**
     * 构建一个成功的响应
     * @param data 响应数据
     * @param resultCode 响应状态码
     * @param <T> 响应数据泛型
     */
    public static<T> Result<T> ok(ResultCode resultCode, T data){
        return new Result<T>(resultCode.code(),resultCode.message(),Objects.nonNull(data),data);
    }

    /**
     * 构建一个失败的响应
     * @param resultCode 响应状态码
     */
    public static<T> Result<T> fail(ResultCode resultCode){
        return new Result<T>(resultCode.code(),resultCode.message(),false,null);
    }

    /**
     * 构建一个失败的响应
     * @param resultCode 响应状态码
     */
    public static<T> Result<T> fail(ResultCode resultCode, T data){
        return new Result<T>(resultCode.code(),resultCode.message(),false,data);
    }

    /**
     * 构建一个响应
     * @param resultCode 响应状态码信息
     * @param data 响应数据
     * @param success 响应数据成功标识
     * @return 响应对象
     * @param <T> 响应数据泛型
     */
    public static<T> Result<T> build(ResultCode resultCode, T data, boolean success){
        return new Result<T>(resultCode.code(), resultCode.message(), success, data);
    }

    /**
     * 构建一个响应,如果数据不为null则认为success为true
     * @param resultCode 响应状态码信息
     * @param data 响应数据
     * @return 响应对象
     * @param <T> 响应数据泛型
     */
    public static<T> Result<T> build(ResultCode resultCode, T data){
        return new Result<T>(resultCode.code(), resultCode.message(), Objects.nonNull(data), data);
    }

    /**
     * 设置响应状态码枚举类
     */
    public void setResultCode(ResultCode resultCode) {
        this.code = resultCode.code();
        this.message = resultCode.message();
    }
}
